"""
使用示例：
def price_list(request):
    queryset = models.PricePolicy.objects.all().order_by("count")
    pager = Pagination(request, queryset, page_size=10)
    return render(request, "price_list.html", {"pager": pager})

`price_list.html`文件
<table class="table table-bordered">
        <thead>
        <tr>
            <th>ID</th>
            <th>数量</th>
            <th>价格</th>
            <th>选项</th>
        </tr>
        </thead>
        <tbody>
        {% for obj in pager.get_queryset %}
            <tr>
                <td>{% forloop_counter request forloop.counter %}</td>
                <td>{{ obj.count }}</td>
                <td>{{ obj.price }}</td>
                <td>
                    <a href="{% url_plus request 'price_edit' uid=obj.id %}" class="btn btn-success btn-xs">编辑</a>
                    <a href="{% url_plus request 'price_delete' uid=obj.id %}" class="btn btn-danger btn-xs">删除</a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

    {{ pager.gen_html }}
"""
import copy

from django.utils.safestring import mark_safe


class Pagination:
    """ 分页 """

    def __init__(self, request, queryset, page_size=10):
        """
        封装参数
        :param request: 将`request`传给分页对象，获取`page`参数
        :param queryset: 将`queryset`（全部数据）传给分页对象，分页对象根据url中`page`返回对应数据
        :param page_size: `page_size`的传入
        """
        self.request = request
        self.queryset = queryset
        self.page_size = page_size

        # 计算总页数
        total_count = queryset.count()
        page_size = self.page_size
        page_count, remainder = divmod(total_count, page_size)
        if remainder != 0:
            page_count += 1
        self.page_count = page_count

        # 处理url中page参数
        page = request.GET.get("page", "1")
        if not page.isdecimal():
            page = 1
        else:
            page = int(page)
            if page < 1 or page > page_count:
                page = 1
        self.page = page

        # 封装request.GET（深拷贝）
        self.query_dict = copy.deepcopy(request.GET)
        self.query_dict._mutable = True

    def gen_html(self):
        """ 生成分页的html """
        # 首部
        self.query_dict.setlist('page', [1])
        html_list = ["<ul class='pagination'>", f"<li><a href='?{self.query_dict.urlencode()}'>首页</a></li>"]

        # 上一页
        if self.page == 1:
            html_list.append(f"<li class='disabled'><a>上一页</a></li>")
        else:
            self.query_dict.setlist('page', [self.page - 1])
            html_list.append(f"<li><a href='?{self.query_dict.urlencode()}'>上一页</a></li>")

        # 中间数字
        if self.page_count <= 11:
            # 页数小于等于11页
            for i in range(1, self.page_count + 1):
                self.query_dict.setlist('page', [i])
                if i == self.page:
                    html_list.append(f"<li class='active'><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")
                else:
                    html_list.append(f"<li><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")

        else:
            # 大于11页（总共11个）(5+1+5)
            if self.page < 6:
                # 处理前5个
                for i in range(1, 11 + 1):
                    self.query_dict.setlist('page', [i])
                    if i == self.page:
                        html_list.append(f"<li class='active'><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")
                    else:
                        html_list.append(f"<li><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")
            elif self.page > self.page_count - 5:
                # 处理后5个
                for i in range(self.page_count - 10, self.page_count + 1):
                    self.query_dict.setlist('page', [i])
                    if i == self.page:
                        html_list.append(f"<li class='active'><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")
                    else:
                        html_list.append(f"<li><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")
            else:
                # 其他
                for i in range(self.page - 5, self.page + 5 + 1):
                    self.query_dict.setlist('page', [i])
                    if i == self.page:
                        html_list.append(f"<li class='active'><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")
                    else:
                        html_list.append(f"<li><a href='?{self.query_dict.urlencode()}'>{i}</a></li>")

        # 下一页
        if self.page == self.page_count:
            html_list.append(f"<li class='disabled'><a>下一页</a></li>")
        else:
            self.query_dict.setlist('page', [self.page + 1])
            html_list.append(f"<li><a href='?{self.query_dict.urlencode()}'>下一页</a></li>")

        # 尾部
        self.query_dict.setlist('page', [self.page_count])
        html_list.extend([
            f"<li><a href='?{self.query_dict.urlencode()}'>尾页</a></li>",
            f"<li class='disabled'><a>总共{self.queryset.count()}条{self.page_count}页</a></li>",
            "</ul>"
        ])

        # 处理html
        html_str = "".join(html_list)
        html = mark_safe(html_str)

        return html

    def get_queryset(self):
        """ 返回page对应数据 """
        start = (self.page - 1) * self.page_size
        end = self.page * self.page_size

        # 如果是最后一页
        if self.page == self.page_count:
            return self.queryset[start:]

        return self.queryset[start:end]